package com.devicemantra.coordinate.operations;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.devicemantra.coordinate.dataobjects.CStateFactory;
import com.devicemantra.coordinate.exceptions.dataobjects.CDatabaseException;
import com.devicemantra.coordinate.exceptions.jaxb.CJAXBException;
import com.devicemantra.coordinate.exceptions.operations.CException;
import com.devicemantra.coordinate.exceptions.operations.CParameterNotFoundException;
import com.devicemantra.coordinate.exceptions.operations.CReadPayloadException;
import com.devicemantra.coordinate.exceptions.operations.CStateAlreadyExistsException;
import com.devicemantra.coordinate.exceptions.operations.CWritePayloadException;
import com.devicemantra.coordinate.interfaces.http.CHttpReader;
import com.devicemantra.coordinate.interfaces.http.CHttpWriter;
import com.devicemantra.coordinate.jaxb.JAXBRequestFactory;
import com.devicemantra.coordinate.jaxb.OperationType;
import com.devicemantra.coordinate.jaxb.Request;
import com.devicemantra.coordinate.jaxb.State;

public class AddStateImpl implements COperation {
	
	private CResponseBuilder mResponseBuilder = null;
	private CRequestBuilder mRequestBuilder = null;
	private OperationType mOperationType = OperationType.ADD_STATE;
	HttpServletRequest mHTTPRequest = null;
	HttpServletResponse mHTTPResponse = null;
	
	
	public AddStateImpl() {
		mResponseBuilder = new CResponseBuilder();
	}

	@Override
	public String getResponse() {
		return null;
	}

	@Override
	public void processEvent(HttpServletRequest pHTTPRequest, 
			HttpServletResponse pHTTPResponse) throws CException {
		mHTTPRequest = pHTTPRequest;
		mHTTPResponse = pHTTPResponse;
		mRequestBuilder = new CRequestBuilder(mHTTPRequest);
		String lNewStateName = null;
		/* Optimistic setting of status code and response string */
		mResponseBuilder.setStatus(200, "Success Operation executed");
		try {
			mRequestBuilder.processEvent();
		}catch (CJAXBException e1) {			// TODO Auto-generated catch block
			mResponseBuilder.setStatus(500, "FATAL: JAXB Could not parse request :" );
			e1.printStackTrace();
			throw new CException(e1.getMessage());
		} catch (CReadPayloadException e) {
			// TODO Auto-generated catch block
			mResponseBuilder.setStatus(500, "FATAL: Could not read XML Stream" );
			e.printStackTrace();
		} 
		
		OperationType lOpType = mRequestBuilder.getOperationType();
		
		if( mOperationType != lOpType ) {
			mResponseBuilder.setStatus(409, "CONFLICT ERROR: Request does not match Url : Request directed at " + lOpType + " Destination was " + mOperationType);
			throw new CException("ERROR: Request does not match Url : Request directed at " + lOpType + " Destination was " + mOperationType);
		}
		
		Request lRequest = mRequestBuilder.getRequestObj();
		State lState = lRequest.getCRequestData().getCState();
		if(lState != null )
		{
			lNewStateName = lState.getName();
		}
		else
		{
			mResponseBuilder.setStatus(500, "ADD_STATE Request without a statename ");
			throw new CException("PANIC: ADD_STATE Request without a statename");
		}
		
		try {
			CStateFactory.createNewState(lNewStateName);
		} catch (CDatabaseException e) {
			mResponseBuilder.setStatus(500, "Internal Server Error : Could not persist to database");
			throw new CException(e.getMessage());
		} catch (CStateAlreadyExistsException e) {
			mResponseBuilder.setStatus(420, "State Already Exists");
			throw new CException(e.getMessage());
		}
	}

	@Override
	public void sendResponse() throws CException {
		try {
			CHttpWriter.writeAsString(mHTTPResponse, mResponseBuilder.getAsXML());
		} catch (CWritePayloadException e) {
			e.printStackTrace();
			mResponseBuilder.setStatus(420, "State Already Exists");
			throw new CException(e.getMessage());
		} catch (CException e) {
			e.printStackTrace();
			mResponseBuilder.setStatus(420, "State Already Exists");
			throw new CException(e.getMessage());
		}
			
	}

}
